
package com.borqs.music.ui.online;

import static android.content.DialogInterface.BUTTON_NEGATIVE;
import static android.content.DialogInterface.BUTTON_POSITIVE;
import static com.borqs.music.tasks.SongTask.PAGE_COUNT;
import static com.borqs.music.ui.adapter.OnlineTrackListAdapter.TYPE_NORMAL;
import static com.borqs.music.ui.adapter.OnlineTrackListAdapter.TYPE_STATUS;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.EditText;
import android.widget.ListView;

import com.borqs.music.R;
import com.borqs.music.database.CacheUtils;
import com.borqs.music.database.CacheUtils.SongCache;
import com.borqs.music.executor.MusicExecutor;
import com.borqs.music.executor.Task;
import com.borqs.music.executor.TaskAdapter;
import com.borqs.music.executor.TaskListener;
import com.borqs.music.model.SongInfo;
import com.borqs.music.tasks.CreateStreamTask;
import com.borqs.music.tasks.GetAllSongTask;
import com.borqs.music.tasks.GetSongsTask;
import com.borqs.music.ui.adapter.OnlineTrackListAdapter;
import com.borqs.music.ui.adapter.OnlineTrackListAdapter.Status;
import com.borqs.music.util.AccountUtils;
import com.borqs.music.util.BpcApiUtils;
import com.borqs.music.util.MusicUtils;
import com.borqs.music.util.MyLogger;

public class OnlineTrackBrowserActivity extends OnlineBaseActivity {
    static final MyLogger logger = MyLogger.getLogger("OnlineTrackBrowserActivity");

    public static final String SCHEME = "borqs://music/mylist";

    public static final String KEY_TYPE = "TRACK.TYPE";
    public static final String KEY_SINGER = "TRACK.SINGER";

    public static final int TYPE_HOT = 1;
    public static final int TYPE_LATEST = 2;
    public static final int TYPE_SINGER = 3;
    public static final int TYPE_SHARED = 4;

    private List<SongInfo> mSongInfoList = new ArrayList<SongInfo>();
    private OnlineTrackListAdapter mListAdapter;
    private int mPageNumber = 0;
    private int mType = TYPE_HOT;
    private String mSingerName = null;
    private String mUserName = null;
    private long mUserid;

    private int mSelectedPosition;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        mType = intent.getIntExtra(KEY_TYPE, TYPE_SHARED);

        if (mType == TYPE_SINGER) {
            mSingerName = intent.getStringExtra(KEY_SINGER);
        } else if (mType == TYPE_SHARED) {
            mUserid = intent.getLongExtra(BpcApiUtils.User.USER_ID, -1);
            if (mUserid < 0) {
                logger.d("Invalidate uid, uid = " + mUserid);
                finish();
            }

            mUserName = intent.getStringExtra(BpcApiUtils.User.USER_NAME);
        }

        setActivityTitle();

        if (mType == TYPE_HOT || mType == TYPE_LATEST) {
            // only cache for TYPE_DOWNLOAD, TYPE_LATEST
            List<SongInfo> songs = null;
            if (mType == TYPE_HOT)
                songs = SongCache.get(this, CacheUtils.CACHE_TYPE_HOT);
            else if (mType == TYPE_LATEST)
                songs = SongCache.get(this, CacheUtils.CACHE_TYPE_LATEST);

            mSongInfoList.addAll(songs);
        }

        mListAdapter = new OnlineTrackListAdapter(this, mSongInfoList);
        setListAdapter(mListAdapter);
        mHandler.sendEmptyMessage(MSG_LOAD_START);
    }

    private void setActivityTitle() {
        CharSequence fancyName = null;
        if (mType == TYPE_LATEST) {
            fancyName = getString(R.string.online_track_browser_title_latest_songs);
        } else if (mType == TYPE_SINGER) {
            fancyName = mSingerName;
        } else if (mType == TYPE_SHARED) {
            fancyName = getString(R.string.stream_shared_musics_title, mUserName);
        } else {
            fancyName = getString(R.string.tracks_title);
        }

        setTitle(fancyName);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        AdapterContextMenuInfo mi = (AdapterContextMenuInfo) menuInfo;
        if (mi.position >= mSongInfoList.size()) {
            //The last list item is additional footbar
            return;
        }
        mSelectedPosition = mi.position;
        menu.add(0, DOWNLOAD_SONG, 0, R.string.download_song);
        menu.add(0, SHARE_BY_STREAM, 0, R.string.share_stream);

        menu.setHeaderTitle(mSongInfoList.get(mSelectedPosition).title);

    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case DOWNLOAD_SONG: {
                SongInfo song = mSongInfoList.get(mSelectedPosition);
                downloadSingleSong(song, true);
                return true;
            }
            case SHARE_BY_STREAM: {
                if (!MusicUtils.checkBorqsAccount(this.getParent())) {
                    return true;
                }
                AdapterContextMenuInfo mi = (AdapterContextMenuInfo) item.getMenuInfo();
                SongInfo song = mSongInfoList.get(mi.position);
                Bundle bundle = new Bundle();
                bundle.putParcelable("songinfo", song);
                showDialog(DIALOG_ID_INPUT, bundle);
                return true;
            }
        }
        return super.onContextItemSelected(item);
    }

    private void createStreamPost(String ticket, SongInfo song, String msg) {
        String msgFormat = getString(R.string.stream_summary_format);
        CreateStreamTask streamTask = new CreateStreamTask(ticket, song, msg, msgFormat);
        streamTask.setListener(streamListener);
        MusicExecutor.getInstance().execute(streamTask);
    }

    private TaskListener streamListener = new TaskAdapter() {
        @Override
        public void onDone(Task task) {
            // assume OK when Done
            showToast(R.string.share_stream_success);
        }

        @Override
        public void onFail(Task task) {
            if (!MusicUtils.checkSessionExpired(
                    OnlineTrackBrowserActivity.this,
                    task.getErrorReason().code)) {
                showToast(R.string.share_stream_failed);
            }
        }
    };

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        if (!checkActiveNetworkStatus()) {
            return;
        }

        int type = mListAdapter.getItemViewType(position);
        if (type == TYPE_STATUS) {
            if (mListAdapter.getStatus() != Status.LOADING) {
                mHandler.sendEmptyMessage(MSG_LOAD_START);
            }
            return;
        }

        if (type == TYPE_NORMAL) {
            playsong(mSongInfoList, position);
            return;
        }
    }

    private TaskListener getSongsListener = new TaskAdapter() {

        @Override
        public void onDone(Task task) {
            Message msg = mHandler.obtainMessage(MSG_LOAD_COMPLETE);
            msg.obj = task.getResult();
            mHandler.sendMessage(msg);
        }

        @Override
        public void onFail(Task task) {
            mHandler.sendEmptyMessage(MSG_LOAD_FAILED);
        }
    };

    private final int MSG_LOAD_START = 1;
    private final int MSG_LOAD_COMPLETE = 2;
    private final int MSG_LOAD_FAILED = 3;
    private final int MSG_FAVOR_SUCCESS = 4;
    private final int MSG_FAVOR_FAILED = 5;

    Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_LOAD_START:
                    mListAdapter.setStatus(Status.LOADING);
                    mListAdapter.notifyDataSetChanged();
                    requestContent(mPageNumber);
                    break;
                case MSG_LOAD_COMPLETE:
                    @SuppressWarnings("unchecked")
                    List<SongInfo> songs = (List<SongInfo>) msg.obj;
                    if (mPageNumber == 0) {
                        if (mType == TYPE_HOT || mType == TYPE_LATEST) {
                            // only cache for TYPE_DOWNLOAD, TYPE_LATEST
                            mSongInfoList.clear(); // clean the cached data
                            Context context = OnlineTrackBrowserActivity.this;
                            // save the new data
                            if (mType == TYPE_HOT)
                                SongCache.put(context, CacheUtils.CACHE_TYPE_HOT, songs);
                            else if (mType == TYPE_LATEST)
                                SongCache.put(context, CacheUtils.CACHE_TYPE_LATEST, songs);
                        }
                    }
                    mSongInfoList.addAll(songs);
                    if (songs.size() < PAGE_COUNT) {
                        mListAdapter.setStatus(Status.NONE);
                    } else {
                        mListAdapter.setStatus(Status.MORE);
                    }
                    mListAdapter.notifyDataSetChanged();
                    mPageNumber++;
                    break;
                case MSG_LOAD_FAILED:
                    mListAdapter.setStatus(Status.FAILED);
                    mListAdapter.notifyDataSetChanged();
                    break;
                case MSG_FAVOR_SUCCESS:
                    showToast(msg.arg1);
                    break;
                case MSG_FAVOR_FAILED:
                    showToast(msg.arg1);
                    break;
            }
        }
    };

    private void requestContent(int page) {
        if (mType == TYPE_SHARED) {
            GetSongsTask task = new GetSongsTask(getSongsListener, mTicket, mUserid, page);
            task.setFileType("mp3");
            MusicExecutor.executeTask(task);
        } else {
            String sort = "";
            if (mType == TYPE_HOT) {
                sort = GetAllSongTask.SORT_BY_DOWNLOAD;
            } else if (mType == TYPE_LATEST) {
                sort = GetAllSongTask.SORT_BY_LATEST;
            }

            Task task = new GetAllSongTask(getSongsListener, mTicket, mSingerName, sort, page);
            MusicExecutor.executeTask(task);
        }
    }

    private static final int DIALOG_ID_INPUT = 0;

    @Override
    public Dialog onCreateDialog(int id, Bundle args) {
        if (id == DIALOG_ID_INPUT) {
            // This example shows how to add a custom layout to an AlertDialog
            LayoutInflater factory = LayoutInflater.from(this);
            final View textEntryView = factory.inflate(R.layout.stream_add_comments, null);
            return new AlertDialog.Builder(getRealActivity(this))
                    .setTitle(R.string.stream_add_comments_title)
                    .setIcon(android.R.drawable.ic_dialog_info)
                    .setView(textEntryView)
                    .setPositiveButton(R.string.stream_add_comments_ok, null)
                    .setNegativeButton(R.string.stream_add_comments_cancel, null)
                    .create();
        }
        return null;
    }

    @Override
    public void onPrepareDialog(int id, Dialog dialog, final Bundle args) {
        if (id == DIALOG_ID_INPUT) {
            AlertDialog alertDialog = (AlertDialog) dialog;
            final EditText edit = (EditText) alertDialog.findViewById(R.id.comments_input);
            edit.setText("");
            DialogInterface.OnClickListener dialogClick = new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    if (whichButton == BUTTON_POSITIVE) {
                        String msg = edit.getText().toString();
                        String ticket = AccountUtils.getUserData(getBaseContext(),
                                AccountUtils.BORQS_ACCOUNT_OPTIONS_KEY_SESSION);
                        SongInfo song = args.getParcelable("songinfo");
                        createStreamPost(ticket, song, msg);
                        return;
                    }
                }
            };

            String okStr = getString(R.string.stream_add_comments_ok);
            String cancelStr = getString(R.string.stream_add_comments_cancel);
            alertDialog.setButton(BUTTON_POSITIVE, okStr, dialogClick);
            alertDialog.setButton(BUTTON_NEGATIVE, cancelStr, dialogClick);
        }
    }

}
